package me.zhengjie.minbearwcs.controller.Inbound;

import lombok.RequiredArgsConstructor;
import me.zhengjie.minbearwcs.entity.DTO.transfer.Tuple;
import org.springframework.web.bind.annotation.*;
import me.zhengjie.minbearwcs.entity.DTO.inbound.mes.InboundMesCallAgv;
import me.zhengjie.minbearwcs.entity.DTO.inbound.mes.InboundPalletConfirm;
import me.zhengjie.minbearwcs.entity.DTO.inbound.mes.InboundPalletContinue;
import me.zhengjie.minbearwcs.entity.DTO.inbound.mes.InboundPalletRollback;
import me.zhengjie.minbearwcs.entity.DTO.inbound.mes.order.MesInboundOrder;
import me.zhengjie.minbearwcs.entity.DTO.response.Resp;
import me.zhengjie.minbearwcs.serivce.inbound.InboundService;

import java.util.Map;

@RestController
@RequiredArgsConstructor
public class InboundMesController {

    private final InboundService inboundService;

    // 接收入库工单
    @PostMapping("/inbound/dispatch")
    public Resp inboundOrderReceive(@RequestBody MesInboundOrder receive) {
//        inboundService.receiveInboundOrder(receive);
        return Resp.build();
        /**
         * 1. controller 接收入库工单，返回接收成功信息
         * 2. service 把工单放到 数据库
         *   2.1 工单基础（工单号，工单类型、初始工单状态。。。）信息新增到 入库工单表 + 入库工单明细表
         *   2.2 把栈板新增到栈板表（栈板号、工单号）
         *   2.3 把小箱信息新增到 物料表 （小箱号，中箱号。。）
         */
    }


    // 入库工单完成通知
    @PostMapping("/inbound/complete")
    public Resp inboundOrderComplete(@RequestBody Map<String,String> infoReq) {
        String inboundOrderCode = infoReq.get("inboundOrderCode");
        Tuple<String> stringTuple = inboundService.inboundOrderComplete(inboundOrderCode);
        return Resp.build()
                .code(stringTuple.success)
                .reason(stringTuple.value);
        /**
         *
         * 1.找到对应入库工单 （入库工单表）
         * 2.更新工单状态以及结束时间
         * 3.找到对应工单明细
         * 4.把工单信息和明细放到对应历史表里
         *
         */
    }


    // 使用mes pda叫车
    @Deprecated
    @PostMapping("/inbound/call/agv")
    public Resp inboundCallAgv(@RequestBody InboundMesCallAgv inboundMesCallAgv) {
//        Tuple<String> tuple = inboundService.receiveMesCallAgv(inboundMesCallAgv);
//        return Resp.build().code(tuple.success)
//                .reason(tuple.value);
        return Resp.build();
        /**
         *
         *  1. 检测当前栈板对应的工单明细状态是否为开始状态，是则返回，防止冲出重复叫车
         *  2. 更新明细状态为开始状态
         *  3. 找到对应的入库策略（任务生成器），生成入库任务
         *      3.1 生成批次号 （入库工单号 + 入库日期）
         *      3.2 给物料表（小箱） 和 栈板表 更新批次号
         *      3.3 判断物料信息有无维护,没有则生成3/4F类型任务
         *      3.4 寻找5/6F合适的储位，并更新到 工单明细表，生成5/6F入库类型任务
         *      3.5 没有找到5/6F合适储位，生成3/4F类型任务
         *  4. 步骤3报错，则把明细状态切换回 等待叫车状态
         *
         *
         */


        /**
         *  3/4F类型任务：
         *  1. 查找 3/4F 空储位
         *      1.1 找到则更新到工单明细，并把任务状态切换为 等待下发状态
         *          没找到则返回，等待下一轮循环再找
         *
         *  2. 生成 AGV任务，并把状态切换为 正在下发状态 ，防止重复下发，
         *      下发成功后，状态切换为 执行中
         *      下发失败，则切换回 等待下发状态
         *
         *  3. 检测AGV任务是否结束，结束则把AGV任务放到AGV历史任务表，
         *      并把wcs任务也放到历史任务表里
         *
         *
         */


        /**
         *
         * 3/4F储位查找策略：
         * 1.获取3F所有储位，按照中储位分组，统计组内储位有栈板或已预订的数量
         * 2.找到数量少于2的中储位，并按照行号排序，找到行号最小的中储位
         *
         */


        /**
         *  5/6F类型任务：
         *  1. 查找 5/6F 交接区空储位
         *      1.1 找到则更新到工单明细，并把任务状态切换为 交接区任务等待下发状态
         *          没找到则返回，等待下一轮循环再找
         *
         *  2. 生成去交接区的AGV任务
         *  3. 监测 去交接区任务是否完成 ，完成则wcs任务状态切换为 等待确认账物是否一致状态
         *  4. 账物一致确认后：如果一致则切换为 等待下发入库任务
         *                  否则切换为 入库异常状态
         *
         *      4.1 如果wcs任务状态为 等待下发入库任务 ，
         *          则生成AGV任务，并把wcs任务状态切换为 正在执行入库任务状态，
         *          执行完成后，切换为 完成状态 ，并把对应的AGV任务 和 wcs任务 放到历史任务表
         *
         *      4.2 如果wcs任务状态为 入库异常状态，
         *          则等待 继续入库通知 和 退回产线通知
         *          ① 接到 继续入库通知 后，切换为 等待下发入库任务 状态，并执行4.1流程
         *          ② 接到退回产线通知后，wcs任务状态切换为 退回产线 状态，
         *              找到 对应产线异常处理区的 空储位 ，
         *              找到后，生成 AGV任务
         *
         *
         */


        /**
         *
         * 5/6F储位查找策略：
         * 1.先找物料号，单号，批次号相同且已经放了货物还有空位的中储位
         * 2.找到同一订单的大储位
         * 3.找到有同一物料编号的楼层，按照大储位编号顺序，找到空的中储位，没有则找另外一层
         *
         * 4。同一订单的大储位 -》放两个批次策略
         * 5.找到有同一物料编号的楼层，按照大储位编号顺序 -》放两个批次策略
         *      没有则找另外一层 -》放两个批次策略
         *
         * 放两个批次策略：
         * 找到只放了一个批次 ，没有出入库锁定，且有空位的中储位
         *
         */
    }


    // 入库确认是否账物一致
    @PostMapping("/inbound/confirm")
    public Resp inboundPalletConfirm(@RequestBody InboundPalletConfirm inboundPalletConfirm) {
        Tuple<String> tuple = inboundService.inboundPalletConfirm(inboundPalletConfirm);
        return Resp.build()
                .reason(tuple.value)
                .code(tuple.success);

        /**
         *
         *  账物一致：
         *  1.找到到对应的wcs任务
         *  2.把对应的wcs任务状态切换为 等待下发入库任务
         *
         *  账物不一致：
         *  1.找到到对应的wcs任务
         *  2.把对应的wcs任务状态切换为 入库异常状态
         *
         */
    }

    // 入库异常处理完成后，继续入库
    @Deprecated
    @PostMapping("/inbound/continue")
    public Resp inboundPalletContinue(@RequestBody InboundPalletContinue inboundPalletContinue) {
        inboundService.inboundPalletContinue(inboundPalletContinue);
        return Resp.build();

        /**
         *
         *
         *  1.找到到对应的wcs任务
         *  2.把对应的wcs任务状态切换为 等待下发入库任务
         *
         */
    }

    // 入库异常后，退回产线通知
    @Deprecated
    @PostMapping("/inbound/rollback")
    public Resp inboundPalletRollback(@RequestBody InboundPalletRollback inboundPalletRollback) {
        inboundService.inboundPalletRollback(inboundPalletRollback);
        return Resp.build();

        /**
         *
         *
         *  1.找到到对应的wcs任务
         *  2.把对应的wcs任务状态切换为 退回产线 状态
         *
         */
    }

}
